package com.ibeeking.found.cop.cp.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.constants.GlobalConstant;
import com.ibeeking.found.cop.cp.rest.service.ICopDepartmentService;
import com.ibeeking.found.cop.service.common.bo.CopDepartmentUnionEmployeeBO;
import com.ibeeking.found.cop.service.common.dos.CopDepartmentDO;
import com.ibeeking.found.cop.service.common.dos.CopEmployeeDO;
import com.ibeeking.found.cop.service.common.query.CopDepartmentQuery;
import com.ibeeking.found.cop.service.common.vo.CopDepartmentVO;
import com.ibeeking.found.cop.service.mapper.CopDepartmentMapper;
import com.ibeeking.found.cop.service.mapper.CopEmployeeMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.TreeFastUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @ClassName CopDepartmentServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class CopDepartmentServiceImpl extends ServiceImpl<CopDepartmentMapper, CopDepartmentDO> implements ICopDepartmentService {

    @Resource
    private CopDepartmentMapper copDepartmentMapper;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Override
    public List<CopDepartmentVO> list(CopDepartmentQuery query){
        LambdaQueryWrapper<CopDepartmentDO> queryWrapper = new LambdaQueryWrapper<>(CopDepartmentDO.class)
                .eq(query.getId()!= null, CopDepartmentDO::getId, query.getId())
                .eq(query.getParentId() != null, CopDepartmentDO::getParentId, query.getParentId())
                .eq(StringUtils.isNotEmpty(query.getName()), CopDepartmentDO::getName, query.getName())
                .eq(StringUtils.isNotEmpty(query.getNickName()), CopDepartmentDO::getNickName, query.getNickName())
                .orderByAsc(CopDepartmentDO::getSort);
        List<CopDepartmentDO> copDepartmentDOS = copDepartmentMapper.selectList(queryWrapper);
        List<CopDepartmentVO> copDepartmentVOS = JsonUtils.jsonToList(copDepartmentDOS, CopDepartmentVO.class);
        return copDepartmentVOS;
    }

    @Override
    public List<Long> getDepartmentIdWithSubByParentId(Long parentId){
        if (null == parentId) return Collections3.emptyList();

        LambdaQueryWrapper<CopDepartmentDO> queryWrapper = new LambdaQueryWrapper<>(CopDepartmentDO.class);
        queryWrapper.eq(CopDepartmentDO::getParentId, parentId);

        List<CopDepartmentDO> copDepartmentDOS = copDepartmentMapper.selectList(queryWrapper);
        if (Collections3.isEmpty(copDepartmentDOS)) {
            return Collections3.emptyList();
        }
        List<Long> ids = copDepartmentDOS.stream().map(CopDepartmentDO::getId).collect(Collectors.toList());
        //查询所有
        if(Collections3.isNotEmpty(ids) && ids.size() >0 ) {
            for(Long id:ids){
                if (id != null) {
                    List<Long> subIds = getBean().getDepartmentIdWithSubByParentId(id);
                    ids.addAll(subIds);
                }
            };
        }
        ids.add(parentId);
        return ids;
    }

    @Override
    public List<CopDepartmentVO> listByParentId(Long parentId){
        if (null == parentId) {
            parentId = GlobalConstant.PARENT_ID;
        }
        LambdaQueryWrapper<CopDepartmentDO> queryWrapper = new LambdaQueryWrapper<>(CopDepartmentDO.class);
        queryWrapper.eq(CopDepartmentDO::getParentId, parentId);

        List<CopDepartmentDO> copDepartmentDOS = copDepartmentMapper.selectList(queryWrapper);
        if (Collections3.isEmpty(copDepartmentDOS)) {
            return Collections3.emptyList();
        }
        List<Long> ids = copDepartmentDOS.stream().map(CopDepartmentDO::getId).collect(Collectors.toList());
        ids.add(parentId);
        //查询所有
        List<CopDepartmentDO> allCopDepartmentDOS = copDepartmentMapper.selectList(new LambdaQueryWrapper<>(CopDepartmentDO.class)
                .orderByAsc(CopDepartmentDO::getSort)
                .orderByDesc(CopDepartmentDO::getCreateTime)
        );
        List<CopDepartmentVO> allCopDepartmentTrees = JsonUtils.jsonToList(allCopDepartmentDOS, CopDepartmentVO.class);
        List<Long> result = new ArrayList<>();
        TreeFastUtils.selectLongCidByPid(result, allCopDepartmentTrees, ids);
        result.addAll(ids);
        allCopDepartmentTrees = allCopDepartmentTrees.stream().filter(g -> result.contains(g.getId())).collect(Collectors.toList());
        List<CopDepartmentVO>  copDepartmentVOS = TreeFastUtils.listToTree(allCopDepartmentTrees, parentId);
        return  copDepartmentVOS;
    }

    @Override
    public List<CopDepartmentUnionEmployeeBO> listAllDepartmentUnionEmployee(Long parentId){
        List<CopDepartmentUnionEmployeeBO> copDepartmentUnionEmployeeBOList = new ArrayList<>();
        List<CopDepartmentDO> allCopDepartmentDOS = copDepartmentMapper.selectList(new LambdaQueryWrapper<>(CopDepartmentDO.class));
        List<Long> allDepartmentIds = new ArrayList<>();
        if (Collections3.isNotEmpty(allCopDepartmentDOS)) {
            allDepartmentIds.add(parentId);
            List<CopDepartmentVO> allCopDepartmentTrees = JsonUtils.jsonToList(allCopDepartmentDOS, CopDepartmentVO.class);
            List<Long> mainDepartmentIds= new ArrayList<>();
            mainDepartmentIds.add(parentId);
            List<Long> result = new ArrayList<>();
            TreeFastUtils.selectLongCidByPid(result, allCopDepartmentTrees, mainDepartmentIds);
            allDepartmentIds.addAll(result);
        }
        if(Collections3.isNotEmpty(allDepartmentIds)){
            List<CopDepartmentDO> allFiltCopDepartmentDOS = copDepartmentMapper.selectList(new LambdaQueryWrapper<CopDepartmentDO>().in(CopDepartmentDO::getId,allDepartmentIds));
            if (Collections3.isNotEmpty(allFiltCopDepartmentDOS)) {
                for(CopDepartmentDO d:allFiltCopDepartmentDOS){
                    CopDepartmentUnionEmployeeBO dopDepartmentUnionEmployeeBO = new CopDepartmentUnionEmployeeBO();
                    dopDepartmentUnionEmployeeBO.setId(d.getId());
                    dopDepartmentUnionEmployeeBO.setParentId(d.getParentId());
                    dopDepartmentUnionEmployeeBO.setDepartmentId(d.getId());
                    dopDepartmentUnionEmployeeBO.setEmployeeId(null);
                    dopDepartmentUnionEmployeeBO.setCode(null);
                    dopDepartmentUnionEmployeeBO.setName(d.getName());
                    copDepartmentUnionEmployeeBOList.add(dopDepartmentUnionEmployeeBO);
                };
            }
            List<CopEmployeeDO> allFiltCopEmployeeDOS = copEmployeeMapper.selectList(new LambdaQueryWrapper<CopEmployeeDO>().in(CopEmployeeDO::getMainDepartmentId,allDepartmentIds));
            if (Collections3.isNotEmpty(allFiltCopEmployeeDOS)) {
                for(CopEmployeeDO d:allFiltCopEmployeeDOS){
                    CopDepartmentUnionEmployeeBO dopDepartmentUnionEmployeeBO = new CopDepartmentUnionEmployeeBO();
                    dopDepartmentUnionEmployeeBO.setId(d.getId());
                    dopDepartmentUnionEmployeeBO.setParentId(d.getMainDepartmentId());
                    dopDepartmentUnionEmployeeBO.setDepartmentId(d.getMainDepartmentId());
                    dopDepartmentUnionEmployeeBO.setEmployeeId(d.getId());
                    dopDepartmentUnionEmployeeBO.setCode(d.getEmployeeCode());
                    dopDepartmentUnionEmployeeBO.setName(d.getEmployeeName());
                    copDepartmentUnionEmployeeBOList.add(dopDepartmentUnionEmployeeBO);
                };
            }
        }
        if(Collections3.isNotEmpty(copDepartmentUnionEmployeeBOList)) {
            List<Long> allIds =copDepartmentUnionEmployeeBOList.stream().map(CopDepartmentUnionEmployeeBO::getId).collect(Collectors.toList());
            List < Long > result = new ArrayList<>();
            TreeFastUtils.selectLongCidByPid(result, copDepartmentUnionEmployeeBOList, allIds);
            result.addAll(allIds);
            copDepartmentUnionEmployeeBOList = copDepartmentUnionEmployeeBOList.stream().filter(g -> result.contains(g.getId())).collect(Collectors.toList());
            List<CopDepartmentUnionEmployeeBO> copDepartmentVOS = TreeFastUtils.listToTree(copDepartmentUnionEmployeeBOList, parentId);
            return copDepartmentVOS;
        }else{
            return null;
        }
    }

    private ICopDepartmentService getBean(){
        return SpringBeanUtil.getBean(CopDepartmentServiceImpl.class);
    }
}
